from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
import sentinelsat
import requests
import json
from decimal import Decimal
import shutil
from tqdm import tqdm
import re
import os
try:
    from osgeo import gdal
    from osgeo import ogr
    from osgeo import osr
except ImportError:
    import gdal
    import ogr
    import osr


def GetShapeFileFeatureDictByField(fieldDict, shapeFilePath, layerName=None):
    """
    依据字段获取要素字典
    :param fieldDict:
    :param shapeFilePath:
    :param layerName:
    :return:
    """
    datasource = ogr.Open(shapeFilePath)
    if layerName:
        layer = datasource.GetLayerByName(layerName)
    else:
        layer = datasource.GetLayer(0)
    fieldName = list(fieldDict.keys())[0]
    fieldValue = fieldDict[fieldName]
    layer.SetAttributeFilter("%s='%s'" % (fieldName, fieldValue))
    featureDictList = []
    feature = layer.GetNextFeature()
    while feature is not None:
        featureJson = feature.ExportToJson()
        featureDict = json.loads(featureJson)
        featureDictList.append(featureDict)
        feature = layer.GetNextFeature()
    layer.ResetReading()
    datasource.Destroy()
    return featureDictList


def GetConfigFileParams():
    """
    得到配置文件的参数
    :return:
    """
    currentFolderPath = os.getcwd()
    configJsonFilePath = os.path.join(currentFolderPath, r"s2zoneconfig.json")
    with open(configJsonFilePath, "r") as jsonfile:
        configdict = json.load(jsonfile)
    return configdict


def CountyCodeToSentinel2Zone(countyCode, countyShapeFilePath, layerName=None):
    """
    依据县代码获得哨兵图幅编号
    :param countyCode:
    :param countyShapeFilePath:
    :param layerName:
    :return:
    """
    fieldDict = {"qhdm": countyCode}
    featureDictList = GetShapeFileFeatureDictByField(
        fieldDict, countyShapeFilePath, layerName)
    s2ZoneList = []
    for featureDict in featureDictList:
        featureproperties = featureDict["properties"]
        s2ZoneFieldValue = featureproperties["S2Zone"]
        s2ZoneStrList = s2ZoneFieldValue.split("_")
        for s2ZoneStr in s2ZoneStrList:
            s2ZoneList.append(s2ZoneStr)
    return s2ZoneList


def CheckProductByMGRS(api, sentinel2ZoneList, kwargs=None):
    """
    依据图幅编号下载影像
    :param kwargs:
    :param api:
    :param sentinel2ZoneList:
    :return:
    """
    if kwargs is None:
        kwargs = {
            "date": ('NOW-30DAYS', 'NOW'),
            "platformname": 'Sentinel-2',
            "producttype": "S2MSI2A",  # S2MSI1C
            "cloudcoverpercentage": (0, 30)}
    productAllOrderdDict = OrderedDict()
    for sentinel2Zone in sentinel2ZoneList:
        filename = "*_T%s_*" % sentinel2Zone
        productSingleOrderDict = api.query(
            filename=filename,
            date=kwargs["date"],
            platformname=kwargs["platformname"],
            producttype=kwargs["producttype"],
            cloudcoverpercentage=kwargs["cloudcoverpercentage"])
        api.download(product)
        productAllOrderdDict.update(productSingleOrderDict)
    return productAllOrderdDict


def GetEsaWebApi():
    countyCode = input("请输入县区划代码:  ")
    startTime = input("请输入影像开始时间:  ")
    endTime = input("请输入影像结束时间:  ")
    configdict = GetConfigFileParams()
    saveFolderPath = configdict["saveFolderPath"]
    shapeFilePath = configdict["shapeFilePath"]
    producttype = configdict["producttype"]
    username = configdict["username"]
    password = configdict["password"]
    url = configdict["url"]
    maxcloudcoverpercentage = configdict["maxcloudcoverpercentage"]
    period = (startTime, endTime)
    s2ZoneList = DownloadSentinel2.CountyCodeToSentinel2Zone(countyCode, shapeFilePath)
    print("需要下载的哨兵图幅:", s2ZoneList)
    api = sentinelsat.SentinelAPI(
        username,
        password,
        api_url=url,
        show_progressbars=True,
        timeout=None)
    kwargs = {
        "date": period,
        "platformname": 'Sentinel-2',
        "producttype": producttype,  # S2MSI1C
        "cloudcoverpercentage": (0, maxcloudcoverpercentage)}
    productAllOrderdDict = cls.CheckProductByMGRS(api, s2ZoneList, kwargs)
    productInfoDictList = cls.GetProductInfo(api, productAllOrderdDict, saveFolderPath)
    cls.DelTempJpgFile(saveFolderPath)
    DownloadSentinel2.DownloadProductInfoQuickImage(
        productInfoDictList, saveFolderPath, username, password)
    downloadFlag = input("请删除不需要的影像!\n删除完毕请按: 1,退出下载请按其他键!\n")
    if downloadFlag == "1":
        fileNameList = DownloadSentinel2.FromFolderSelectS2ZoneNoneList(saveFolderPath)
        productAllOrderdDict = DownloadSentinel2.CheckProductByFileName(api, fileNameList)
        # DownloadSentinel2.DownloadMultipleProduct(api, productAllOrderdDict)
        sum = len(productAllOrderdDict)
        for listIndex, product in enumerate(productAllOrderdDict):
            print("正在下载(%d/%d)" % (sum, listIndex))
            productInfoDict = api.get_product_odata(product)
            productName = productInfoDict['title']
            print("Product name:", productName)
            productDate = productInfoDict['date']
            print("Product date:", productDate)
            productSize = productInfoDict['size']
            print("Product size:", productSize)
            api.download(product)
    else:
        return
    return


def DownLoad():
    countyCode = input("请输入县区划代码:  ")
    startTime = input("请输入影像开始时间:  ")
    endTime = input("请输入影像结束时间:  ")
    configdict = GetConfigFileParams()
    saveFolderPath = configdict["saveFolderPath"]
    shapeFilePath = configdict["shapeFilePath"]
    producttype = configdict["producttype"]
    username = configdict["username"]
    password = configdict["password"]
    url = configdict["url"]
    maxcloudcoverpercentage = configdict["maxcloudcoverpercentage"]
    period = (startTime, endTime)
    cloudcoverpercentage = (0, maxcloudcoverpercentage)
    s2ZoneList = CountyCodeToSentinel2Zone(countyCode, shapeFilePath)
    print("需要下载的哨兵图幅:", s2ZoneList)
    api = sentinelsat.SentinelAPI(
        username,
        password,
        api_url=url,
        show_progressbars=True,
        timeout=None)
    for sentinel2Zone in s2ZoneList:
        filename = "*_T%s_*" % sentinel2Zone
        productSingleOrderDictList = api.query(
            filename=filename,
            date=period,
            platformname='Sentinel-2',
            producttype=producttype,
            cloudcoverpercentage=cloudcoverpercentage)
        for productSingleOrderDict in productSingleOrderDictList:
            api.download(productSingleOrderDict)
    return


if __name__ == "__main__":
    DownLoad()